using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using AppExtensions.Presenters;
using AppExtensions.Views;
using System.Web.Security;
using AspNetExtensions.Web.SessionState;
using System.Web;
using System.Threading;
using System.Globalization;

namespace AspNetExtensions.Pages {
  public abstract class BasePage<TPresenter, TView> : Page, IBaseView
    where TPresenter : BasePresenter<TView>, new()
    where TView : IBaseView {
    private SessionDictionaryWrapper sessionWrapper;
    protected TPresenter presenter;

    public BasePage() {
      this.presenter = new TPresenter();
      this.presenter.View = (TView)(object)this;
      this.ContextObject = new Dictionary<string, object>();      
    }
    public Dictionary<string, object> ContextObject { get; private set; }

    protected override void OnPreInit(EventArgs e) {
      base.OnPreInit(e);
      this.sessionWrapper = new SessionDictionaryWrapper(HttpContext.Current.Session);
    }
    protected override void OnInit(EventArgs e) {
      base.OnInit(e);
      this.presenter.Params = this.Request.Params;
      this.presenter.OnViewInitialized();
    }
    protected override void OnLoad(EventArgs e) {
      base.OnLoad(e);
      this.presenter.OnViewLoaded();
      if (!Page.IsPostBack) {
        this.presenter.OnViewFirstLoaded();
      }
    }
    protected override void OnPreRender(EventArgs e) {
      base.OnPreRender(e);
      this.presenter.OnPreRender();
    }
    protected override void InitializeCulture() {
      // TODO Clean up magic strings
      string lang = string.Empty;
      //default to the invariant culture

      if (this.sessionWrapper != null && this.sessionWrapper["Lang"] != null) {
        lang = (string)sessionWrapper["Lang"];
        if (!object.ReferenceEquals(lang, "auto"))
          Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);
        else
          Thread.CurrentThread.CurrentUICulture = CultureInfo.CurrentCulture;
      }
      base.InitializeCulture();
    }

    #region IBaseView Members

    void IBaseView.RedirectTo(string url) {
      Response.Redirect(Server.UrlPathEncode(this.ResolveUrl(url)));
    }

    void IBaseView.RedirectToLogin() {
      // Redirects to the login, but then comes back to this page
      FormsAuthentication.RedirectToLoginPage(Request.RawUrl);
      Response.End();
    }

    void IBaseView.RedirectTo(string url, params KeyValuePair<string, string>[] parameterValues) {
      if (parameterValues.Length > 0) {
        StringBuilder sb = new StringBuilder(url);
        bool isFirst = true;
        foreach (KeyValuePair<string, string> pair in parameterValues) {
          if (isFirst)
            sb.Append("?");
          else
            sb.Append("&");
          sb.AppendFormat("{0}={1}", Server.UrlEncode(pair.Key), Server.UrlEncode(pair.Value));
          isFirst = false;
        }
        url = sb.ToString();
      }
      ((IBaseView)this).RedirectTo(url);
    }

    public void RenderToHandler(IHttpHandler handler) {
      Server.Transfer(handler, true);
    }

    IDictionary<string, object> IBaseView.Session {
      get {
        return this.sessionWrapper;
      }
    }

    string IBaseView.ClientIPAddress {
      get { return Context.Request.UserHostAddress; }
    }

    long? IBaseView.UserId {
      get {
        MembershipUser user = Membership.GetUser(true);
        if (user != null)
          return (long)user.ProviderUserKey;
        else
          return null;
      }
    }
    #endregion

  }
}
